# MusicCacheInotifyHandler - Update cache according to file system changes.
# Copyright (C) 2007 Lauri Taimila
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

__licence__ = "GPLv2"
__copyright__ = "2007, Lauri Taimila"
__author__ = "Lauri Taimila <lauri@taimila.com>"

import os
from pyinotify import ProcessEvent
from backend.components.mediacache.music_cache import MusicCache

class MusicCacheInotifyHandler(ProcessEvent):
    """
    Update cache according to file system changes.'
    
    Object from this class handles inotify events for music cache.
    
    NOTE: MusicCache object is created in every method, because of SQLite
          doesn't allow cursor to be used in separate threads.
    """
    
    def __init__(self, logger, configuration, fs_observer):
        """
        Create a new MusicCacheInotifyHandler object, which handles file system
        changes. In other words, object from this class makes sure that cache is
        always up-to-date.
        """
        self.logger = logger
        self.configuration = configuration
        self.fs_observer = fs_observer

    def process_IN_DELETE(self, event):
        """
        File or directory deleted
        """
        print '%s: deleted' % os.path.join(event.path, event.name) #FIXME: Remove this debug line
        music_cache = MusicCache(self.logger, self.configuration)
        
        # Album art image is removed
        if event.name == "cover.jpg" or event.name == "folder.jpg":
            music_cache.updateDirectory(event.path)
            
        # File deleted - Remove file from cache
        elif music_cache.isSupportedFormat(event.name):
            music_cache.removeFile(os.path.join(event.path, event.name))
        
        # Directory deleted - Remove directory from cache
        else:
            if music_cache.isDirectoryInCache(os.path.join(event.path, event.name)):
                self.fs_observer.removeFolder(os.path.join(event.path, event.name))
                music_cache.removeDirectory(os.path.join(event.path, event.name))

    def process_IN_CREATE(self, event):
        """
        File or directory created
        """
        print '%s: created' % os.path.join(event.path, event.name) #FIXME: Remove this debug line
        music_cache = MusicCache(self.logger, self.configuration)
        
        # Directory created - Add to music cache
        if os.path.isdir(os.path.join(event.path, event.name)): 
            self.fs_observer.addFolder(os.path.join(event.path, event.name), "music")
            music_cache.addDirectory(os.path.join(event.path, event.name))
        
        # Album art image is created
        elif event.name == "cover.jpg" or event.name == "folder.jpg":
            music_cache.updateDirectory(event.path)
            
        # File created - Add audio file to the cache
        else:
            if music_cache.isSupportedFormat(event.name):
                music_cache.addFile(os.path.join(event.path, event.name))
        
    def process_IN_MODIFY(self, event):
        """
        File or directory was modified.
        """
        print '%s: modified' % os.path.join(event.path, event.name) #FIXME: Remove this debug line
        music_cache = MusicCache(self.logger, self.configuration)
        
        # Directory modified - update music cache
        # FIXME: DO WE NEED THIS AT ALL?
        if os.path.isdir(os.path.join(event.path, event.name)): 
            music_cache.updateDirectory(os.path.join(event.path, event.name))
        
        # Album art image is modified
        elif event.name == "cover.jpg" or event.name == "folder.jpg":
            music_cache.updateDirectory(event.path)
            
        # File modified - update music cache
        else:
            if music_cache.isSupportedFormat(event.name):
                music_cache.updateFile(os.path.join(event.path, event.name))
        
    def process_IN_MOVED_FROM(self, event):
        """
        File or directory is moved from observed. (same as delete in our point of view)
        """
        print '%s: IN_MOVED_FROM' % os.path.join(event.path, event.name) #FIXME: Remove this debug line
        self.process_IN_DELETE(event)
        
    def process_IN_MOVED_TO(self, event):
        """
        File or directory is moved in to observed. (same as create in our point of view)
        """
        print '%s: IN_MOVED_TO' % os.path.join(event.path, event.name) #FIXME: Remove this debug line
        self.process_IN_CREATE(event)

    def process_IN_DELETE_SELF(self, event):
        """
        Listened directory was deleted
        """
        print '%s: observed deleted' % os.path.join(event.path, event.name) #FIXME: Remove this debug line
        music_cache = MusicCache(self.logger, self.configuration)
        if music_cache.isDirectoryInCache(os.path.join(event.path, event.name)):
            music_cache.removeDirectory(os.path.join(event.path, event.name))
            self.fs_observer.removeFolder(os.path.join(event.path, event.name))
                
    def process_IN_MOVE_SELF(self, event):
        """
        Observed folder has been moved.
        """
        print '%s: IN_MOVE_SELF' % os.path.join(event.path, event.name) #FIXME: Remove this debug line
        #FIXME: WHAT SHOULD BE DONE HERE?!!
        
    def process_default(self, event):
        """
        Ultimately, this method is called for all others kind of events.
        """
        pass
